package com.common.springbootcommonmessage.utils;

import com.alibaba.fastjson.JSON;
import com.common.springbootcommonmessage.enums.AutoBestErrorCode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.message.ObjectMessage;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

public class LogUtil {

    public final static Logger logger = LogManager.getLogger(LogUtil.class);

    public static void logInfo(String traceId, String method, Object data, String moreInfo, String logType) {
        try {
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, data, moreInfo);
            switch (logType) {
                case "info":
                    logger.info(msg);
                    break;
                case "error":
                    logger.error(msg);
                    break;
                case "debug":
                    logger.debug(msg);
                    break;
                default:
                    logger.info(msg);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, String moreInfo, String logType) {
        try{
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, null, moreInfo);
            switch (logType) {
                case "info":
                    logger.info(msg);
                    break;
                case "error":
                    logger.error(msg);
                    break;
                case "debug":
                    logger.debug(msg);
                    break;
                default:
                    logger.info(msg);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, String moreInfo, int code) {
        try{
            ObjectMessage msg = parseMessage(code, traceId, method, null, moreInfo);
            logger.info(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, Object data, String moreInfo, int code) {
        try {
            ObjectMessage msg = parseMessage(code, traceId, method, data, moreInfo);
            logger.info(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, Object data, String logType) {
        try{
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, data, null);
            switch (logType) {
                case "info":
                    logger.info(msg);
                    break;
                case "error":
                    logger.error(msg);
                    break;
                case "debug":
                    logger.debug(msg);
                    break;
                default:
                    logger.info(msg);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, Object data) {
        try{
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, data, null);
            logger.info(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void logInfo(String traceId, String method, String moreInfo, Object data,  Date startTime) {
        try{
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, data, moreInfo, startTime);
            logger.info(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void warnInfo(String traceId, String method, Object data, String moreInfo) {
        try {
            ObjectMessage msg = parseMessage(AutoBestErrorCode.BACKEND_DATA_CODE.getValue(), traceId, method, data, moreInfo);
            logger.warn(msg);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static ObjectMessage parseMessage(Integer code, String traceId, String method, Object data, String moreInfo) {
        Map<String, Object> map = new TreeMap<>();
        map.put("traceId", traceId);
        map.put("method", method);
        map.put("moreInfo", ( null == moreInfo ? "" : moreInfo ));
        map.put("data", ( null == data ? "{\"code\":200,\"message\":\"success\"}" : JSON.toJSONString(data) ));
        map.put("code", code);
        map.put("codeName", AutoBestErrorCode.valueOf(code).toString());
        map.put("time", DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
        map.put("responseTime(ms)", 0);
        return new ObjectMessage(map);
    }

    private static ObjectMessage parseMessage(Integer code, String traceId, String method, Object data, String moreInfo, Date startTime) {
        Date nowDate = new Date();
        Double useTime = (startTime == null ? 0 : DateUtil.getTimeDiffer(startTime, nowDate));
        Map<String, Object> map = new TreeMap<>();
        map.put("traceId", traceId);
        map.put("method", method);
        map.put("moreInfo", ( null == moreInfo ? "" : moreInfo ));
        map.put("data", ( null == data ? "{\"code\":200,\"message\":\"success\"}" : JSON.toJSONString(data) ));
        map.put("code", code);
        map.put("codeName", AutoBestErrorCode.valueOf(code).toString());
        map.put("time", DateUtil.formatDate(nowDate, "yyyy-MM-dd HH:mm:ss.SSS"));
        map.put("responseTime(ms)", useTime);
        return new ObjectMessage(map);
    }
}